package com.ai.deepseekspring.utils;



import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;

import java.util.Date;

/**
 * @author Luke Ewin
 * @date 2024/2/19 16:59
 * @blog blog.lukeewin.top
 */
public class TokenUtil {

    private final static String ENCRYPT_KEY = "abc123"; // 加密的密钥

    private final static int EXPIRE_TIME = 60; // token 过期时间，单位分钟

    private static final String ISSUER = "zhangsan";

    /**
     * 生成 token
     *
     * @param json 要封装到 token 的内容，如果要传递多个参数内容，可以定义为 JSON 或者 Map
     * @return 返回 token
     */
    public static String createToken(JSONObject json) {
        return JWT.create()
                .withSubject(json.toString()) // 不要把密码封装进去，不安全
                .withIssuer(ISSUER) // 设置发布者
                .withExpiresAt(DateUtil.offsetMinute(new Date(), EXPIRE_TIME)) // 设置过期时间
                .withClaim("test", "123") // 这里是随便设置的内容，类似 Map
                .sign(Algorithm.HMAC256(ENCRYPT_KEY)); // 加密
    }

    /**
     * 验证 token
     *
     * @param token
     * @return
     */
    public static boolean verifyToken(String token) {
        try {
            JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(ENCRYPT_KEY))
                    .withIssuer(ISSUER)
                    .build();
            jwtVerifier.verify(token);
            return true;
        } catch (Exception e) { // 如果 token 过期会报错 TokenExpiredException
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 解析 token，提取其中封装的信息
     * 注意：解析前应先调用verifyToken()验证token有效性
     *
     * @param token 已验证通过的token
     * @return 解析后的JSON对象（包含生成token时封装的信息）
     */
    public static JSONObject parseToken(String token) {
        try {
            // 解码token（不验证签名，因此必须先通过verifyToken验证）
            DecodedJWT decodedJWT = JWT.decode(token);

            // 提取subject中的JSON字符串并转换为JSONObject
            String subject = decodedJWT.getSubject();
            return JSONUtil.parseObj(subject);

        } catch (Exception e) {
            throw new RuntimeException("Token解析失败", e);
        }
    }
}